ASP .NET Core  -  API Usando SQLite com EF Core


  Neste tutorial veremos como criar um projeto Web API ASP .NET Core acessando o SQLite com EF Core.

A grande parte dos artigos usando aplicações ASP .NET Core usa o EF Core acessando o SQL Server ou MySQL. Hoje veremos como podemos usando o SQLite.

Criando o projeto Web API

Abra o VS 2019 e selecione a opção New Project e selecione o template ASP .NET Core Web API e informe o nome SqliteEFCore usando as seguintes configurações:

Vamos incluir o pacote Microsoft.EntityFrameworkCore.Sqlite no projeto:

Repita o procedimento acima e instale também os pacotes :

A seguir crie uma pasta Models no projeto e nesta classe crie a classe Estudante com o código abaixo:

    public class Estudante
    {
        public Guid Id { get; set; }
        public string Nome { get; set; }
        public string Email { get; set; }
        public DateTime Nascimento { get; set; }
        public string Sexo { get; set; }
    }

Nesta pasta Models crie a classe AppDbContext que deve herdar de DbContext e onde vamos definir o mapeamento da entidade Estudante para a tabela Estudantes:

    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
        { }

        public DbSet<Estudante> Estudantes { get; set; }
    }

A seguir no arquivo appsettings.json vamos definir uma seção onde vamos definir a string de conexão com o banco de dados SQLite :

{
  "ConnectionStrings": {
    "SqliteConnectionString": "Data Source=EstudantesDB.db"
  },

  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Após isso abra o arquivo Startup e no método ConfigureServices inclua o serviço para o contexto do SQLite usando a string de conexão definida acima:

public void ConfigureServices(IServiceCollection services)
{

     services.AddControllers();
     services.AddSwaggerGen(c =>
     {
         c.SwaggerDoc("v1", new OpenApiInfo { Title = "SqliteEFCore", Version = "v1" });
    });

    services.AddDbContext<AppDbContext>(options =>
             options.UseSqlite(Configuration.GetConnectionString("SqliteConnectionString")));

}

Agora podemos aplicar o migrations do EF Core. Antes verifique se você possui a ferramenta dotnet-ef instalada no seu ambiente, abrindo uma janela de comandos e digitando o comando :  dotnet tool list --global

A janela abaixo mostra o resultado exibindo a ferramenta dotnet-ef e sua versão. Com isso você poderá usar a ferramenta de linha de comando para aplicar o migrations:

Se você não tiver a ferramenta, para instalar digite o comando :  dotnet tool install --global dotnet-ef

Vamos usar esta ferramenta na janela Package Manager Console do Visual Studio 2019. Para isso abra a janela no menu Tools e a seguir digite o comando: dotnet ef migrations add Inicial -p SqliteEFCore

Aqui -p SqliteEFCore indica o projeto onde o Migrations será criado.

Este código irá criar um script de migração que poderá ser aplicado usando o comando: dotnet ef database update

Uma outra forma de aplicar a Migração é via código. Para isso inclua o código abaixo no método Main da classe Program do projeto :

public class Program
    {
        public static void Main(string[] args)
        {
            var host = CreateHostBuilder(args).Build();

            using var scope = host.Services.CreateScope();

            var services = scope.ServiceProvider;
            try
            {
                var context = services.GetRequiredService<AppDbContext>();
                context.Database.Migrate();
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "Ocorreu um erro durante a Migration");
            }
            host.Run();
        }
  ...
}

Agora ao executar o projeto na classe Program temos o código que vai aplicar a migração e criar o banco de dados EstudantesDB.db na raiz do projeto.

Criando o controlador

Para criar o controlador usando os recursos do Scaffold basta clicar com o botão do mouse sobre a pasta Controllers e selecionar a opção Add -> Controller;

Na janela a seguir, selecione API e a opção - API Controller with actions, using Entity Framework - para gerar o controlador :

A seguir selecione as opções conforme abaixo na janela Add API Controller... :

Isso irá gerar o controlador EstudantesController com seguinte código:

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using SqliteEFCore.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SqliteEFCore.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EstudantesController : ControllerBase

    {
        private readonly AppDbContext _context;

        public EstudantesController(AppDbContext context)
        {
            _context = context;
        }

        [HttpGet]
        public async Task<ActionResult<IEnumerable<Estudante>>> GetEstudantes()
        {
            return await _context.Estudantes.ToListAsync();
        }

        [HttpGet("{id}")]
        public async Task<ActionResult<Estudante>> GetEstudante(Guid id)
        {
            var estudante = await _context.Estudantes.FindAsync(id);

            if (estudante == null)
            {
                return NotFound();
            }

            return estudante;
        }

        [HttpPut("{id}")]
        public async Task<IActionResult> PutEstudante(Guid id, Estudante estudante)
        {
            if (id != estudante.Id)
            {
                return BadRequest();
            }

            _context.Entry(estudante).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!EstudanteExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return NoContent();
        }

        [HttpPost]
        public async Task<ActionResult<Estudante>> PostEstudante(Estudante estudante)
        {
            _context.Estudantes.Add(estudante);
            await _context.SaveChangesAsync();

            return CreatedAtAction("GetEstudante", new { id = estudante.Id }, estudante);
        }

        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteEstudante(Guid id)
        {
            var estudante = await _context.Estudantes.FindAsync(id);
            if (estudante == null)
            {
                return NotFound();
            }

            _context.Estudantes.Remove(estudante);
            await _context.SaveChangesAsync();

            return NoContent();
        }

        private bool EstudanteExists(Guid id)
        {
            return _context.Estudantes.Any(e => e.Id == id);
        }
    }
}

Temos assim a API definida usando os verbos HTTP GET, POST , PUT e DELETE que vai permitir realizar o CRUD básico na tabela EstudantesDB.db

Executando o projeto teremos a apresentação dos endpoints na interface do Swagger:

Temos assim uma API básica criada quase que automaticamente e pronta para ser usada.

Acessando o endpoint POST para incluir um estudante vamos definir os dados conforme abaixo:

Clicando em Execute teremos o resultado abaixo:

Pegue o código do projeto aqui:  SqliteEFCore.zip (sem as referências)

"Toda a Escritura é divinamente inspirada, e proveitosa para ensinar, para redargüir, para corrigir, para instruir em justiça;"
2 Timóteo 3:16

Referências:


José Carlos Macoratti